CC		= g++
LEX		= flex
YACC	= bison

SRCEXT	= .cpp
HDREXT	= .h
OBJEXT	= .o
LEXT	= .l
LSRCEXT	= .yy.cc
LOBJEXT = .yy.o
YEXT	= .y
YSRCEXT	= .tab.c
YOBJEXT = .tab.o
YHDREXT	= .tab.h

SRCDIR	= src
INCDIR 	= include
OBJDIR	= bin
GENDIR	= gen

CFLAGS	= -O2 -std=c++0x -I$(INCDIR) -I$(GENDIR)/$(INCDIR)
LDFLAGS	= 

PROGRAM = lalgc

SRCS	= $(foreach d, $(SRCDIR), $(wildcard $(addprefix $(d)/*, $(SRCEXT))))
HDRS	= $(foreach d, $(INCDIR), $(wildcard $(addprefix $(d)/*, $(HDREXT))))
LEXS	= $(foreach d, $(SRCDIR), $(wildcard $(addprefix $(d)/*, $(LEXT))))
YACCS	= $(foreach d, $(SRCDIR), $(wildcard $(addprefix $(d)/*, $(YEXT))))
LSRCS	= $(addprefix $(GENDIR)/, $(LEXS:$(LEXT)=$(LSRCEXT)))
YSRCS	= $(addprefix $(GENDIR)/, $(YACCS:$(YEXT)=$(YSRCEXT)))
YHDRS	= $(addprefix $(GENDIR)/$(INCDIR)/, $(notdir $(YACCS:$(YEXT)=$(YHDREXT))))
OBJS    = $(addsuffix $(OBJEXT), $(addprefix $(OBJDIR)/, $(basename $(SRCS))))
LOBJS	= $(addsuffix $(OBJEXT), $(addprefix $(OBJDIR)/, $(basename $(LSRCS))))
YOBJS	= $(addsuffix $(OBJEXT), $(addprefix $(OBJDIR)/, $(basename $(YSRCS))))


.PHONY: show all objs clean clean_all
.SUFFIXES:

all: $(PROGRAM)

objs: $(OBJS) $(LOBJS) $(YOBJS)

$(YHDRS): $(YSRCS) $(LSRCS)

$(GENDIR)/%$(LSRCEXT): %$(LEXT)
	mkdir $(dir $@) -p
	$(LEX) -o $@ $<
	
$(GENDIR)/%$(YSRCEXT): %$(YEXT)
	mkdir $(dir $@) -p
	mkdir $(GENDIR)/$(INCDIR) -p
	$(YACC) -o $@ $< -v
	mv $(GENDIR)/$(SRCDIR)/*h $(GENDIR)/$(INCDIR)  

$(OBJDIR)/%$(OBJEXT): %$(SRCEXT) $(HDRS) $(YHDRS)
	mkdir $(dir $@) -p
	$(CC) -c $< -o $@ $(CFLAGS)

$(OBJDIR)/%$(LOBJEXT): %$(LSRCEXT) $(HDRS)
	mkdir $(dir $@) -p
	$(CC) -c $< -o $@ $(CFLAGS)
	
$(OBJDIR)/%$(YOBJEXT): %$(YSRCEXT) $(HDRS) $(YHDRS)
	mkdir $(dir $@) -p
	$(CC) -c $< -o $@ $(CFLAGS)
	
$(PROGRAM): $(OBJS) $(LOBJS) $(YOBJS)
	$(CC) $(OBJS) $(LOBJS) $(YOBJS) -o $(OBJDIR)/$@ $(LDFLAGS)
	@echo Type ./$(OBJDIR)/$@ to execute the program.

clean:
	rm -rf $(GENDIR) $(OBJDIR)/$(SRCDIR) $(OBJDIR)/$(GENDIR)
	
clean_all:
	rm -rf $(OBJDIR) $(GENDIR)
	
show:
	@echo 'PROGRAM     :' $(PROGRAM)
	@echo 'SRCDIR      :' $(SRCDIR)
	@echo 'OBJDIR      :' $(OBJDIR)
	@echo 'SRCS        :' $(SRCS)
	@echo 'HDRS        :' $(HDRS)
	@echo 'LEXS        :' $(LEXS)
	@echo 'YACCS       :' $(YACCS)
	@echo 'LSRCS       :' $(LSRCS)
	@echo 'YSRCS       :' $(YSRCS)
	@echo 'YHDRS       :' $(YHDRS)
	@echo 'OBJS        :' $(OBJS)
	@echo 'LOBJS       :' $(LOBJS)
	@echo 'YOBJS       :' $(YOBJS)
	@echo 'CFLAGS      :' $(CFLAGS)
	@echo 'LIBS        :' $(LIBS)
